from rest_framework.views import APIView
from rest_framework.response import Response
from django.conf import settings
import redis

from .models import Color, Category, GoodsChannel, Brand, Version, SPU, SKU
from myutils.cate_utils import get_categories
from .serializer import *
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import (
    ListModelMixin,  # 展示全部的信息
    CreateModelMixin,   # 创建
    RetrieveModelMixin,   # 按id进行获取，获取单个
    DestroyModelMixin,   # 删除
    UpdateModelMixin  # 修改
)
import uuid

from .models import Order
from myutils.common import check_token
from alipay import AliPay
# 购物车
redis_cart = redis.Redis(db=8)

app_private_key_string = open("{}\\goods\\alipay_key\\app_private_key.txt".format(settings.BASE_DIR)).read()
alipay_public_key_string = open("{}\\goods\\alipay_key\\alipay_public_key.txt".format(settings.BASE_DIR)).read()

alipay = AliPay(
    appid="2016101000652297",
    app_notify_url=None,  # 默认回调url
    app_private_key_string=app_private_key_string,
    # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
    alipay_public_key_string=alipay_public_key_string,
    sign_type="RSA2", # RSA 或者 RSA2
    debug=False,  # 默认False
)


class OrderInfoView(APIView):
    """
    查询 订单信息
    """
    def get(self, request):
        token = request.query_params.get('token')
        out_trade_no = request.query_params.get('out_trade_no')
        # 解析用户信息
        user_info = check_token(token)
        if user_info:
            #
            user_id = user_info.get('user_id')
            # 通过用户id和订单号，去Order表中拿取数据
            order_list = Order.objects.filter(user_id=user_id, out_trade_no=out_trade_no)
            # 从订单数据封装json
            order_data = []
            total = 0
            for order in order_list:
                order_data.append({
                    'id': order.pk,
                    'out_trade_no': order.out_trade_no,
                    'goods_name': order.goods.name,
                    'price': order.goods.price,
                    'counter': order.counter,

                })
                total = order.total
            return Response({'msg': 'OK', 'code': 200, 'data': order_data, 'total': total})
        else:
            return Response({'msg': '请登录', 'code': 400})



class CreateOrderView(APIView):
    """
    生成订单
    """
    def post(self, request):
        """
        token, goods_id, total, 商品数量
        """
        token = request.data.get('token')
        goods_list = request.data.get('goods_list').split(',')
        total = request.data.get('total')
        # 解析用户信息
        user_info = check_token(token)
        # 生成订单号
        out_trade_no = str(uuid.uuid4())

        # bulk_create()   批量添加
        order_list = []
        if user_info:
            user_id = user_info.get('user_id')
            for goods in goods_list:
                order_list.append(Order(
                    out_trade_no=out_trade_no,
                    goods_id=goods,
                    user_id=user_id,
                    counter=redis_cart.hget(user_id, goods).decode(),
                    total=total
                ))
            Order.objects.bulk_create(order_list)
            return Response({'msg': 'OK', 'code': 200, 'out_trade_no': out_trade_no})
        else:
            return Response({'msg': '请登录', 'code': 400})


class PaymentView(APIView):

    """
    支付订单：
        1、拿到用户信息，去结算，需要带回token
        2、解析token，拿到用户id
        3、根据用户信息， 去获取用户所购买的商品['1,2,3']
        4、根据拿到的商品信息，进行金额计算
        5、生成订单号（uuid）
    """
    def post(self, request):
        print(request.data)

        token = request.data.get('token')
        address = request.data.get('address')
        pay_type = request.data.get('pay_type')
        # 需要拿到用户信息
        user_info = check_token(token)
        if user_info:
            user_id = user_info.get('user_id')
            # 如果你是 Python 3的用户，使用默认的字符串即可
            subject = "美多商城"
            # 订单号
            out_trade_no = request.data.get('out_trade_no')
            order_list = Order.objects.filter(user_id=user_id, out_trade_no=out_trade_no)
            order_list.update(address=address)

            # 订单金额
            total = request.data.get('total')
            # 电脑网站支付，需要跳转到https://openapi.alipay.com/gateway.do? + order_string
            order_string = alipay.api_alipay_trade_page_pay(
                out_trade_no=out_trade_no,
                total_amount=total,
                subject=subject,
                return_url="http://127.0.0.1:8000/goods/callback/",
                notify_url="http://127.0.0.1:8000/goods/callback/"  # 可选, 不填则使用默认notify url
            )
            pay_url = 'https://openapi.alipaydev.com/gateway.do?' + order_string
            return Response({'msg': 'OK', 'code': 200, 'pay_url': pay_url})
        else:
            return Response({'msg': '请登录', 'code': 400})


class CallBackView(APIView):
    def get(self, request):
        data = request.query_params
        print(data)
        return Response({'msg': 'OK'})


class SKUView(GenericAPIView, ListModelMixin, CreateModelMixin):

    queryset = SKU.objects.all()
    serializer_class = SKUModelSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)


class DetailView(GenericAPIView, RetrieveModelMixin):

    queryset = SKU.objects.all()
    serializer_class = SKUModelSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)


class SKUDetailView(APIView):
    def get(self, request):
        goods_id = request.query_params.get('goods_id')
        sku_obj = SKU.objects.filter(pk=goods_id).first()
        sku_serializer = SKUModelSerializer(sku_obj)
        return Response(sku_serializer.data)


class CartView(APIView):
    """
    购物车的增删改查
    """
    def post(self, request):
        """
        token, goods_num, goods_id
        """
        token = request.data.get('token')
        goods_num = request.data.get('goods_num')
        goods_id = request.data.get('goods_id')
        # 解析用户id
        user_info = check_token(token)

        if user_info:
            user_id = user_info.get('user_id')
            redis_cart.hincrby(user_id, goods_id, goods_num)
            return Response({'msg': '添加成功', 'code': 200})
        else:
            return Response({'msg': '请重新登录', 'code': 400})

    def get(self, request):
        token = request.query_params.get('token')
        user_info = check_token(token)
        print(user_info)
        # 解析用户信息
        if user_info:

            user_id = user_info.get('user_id')
            cart_dict = redis_cart.hgetall(user_id)
            print(cart_dict)
            cart_list = []
            for k, v in cart_dict.items():
                sku_obj = SKU.objects.get(pk=k.decode())
                cart_list.append({
                    'id': sku_obj.pk,
                    'name': sku_obj.name,
                    'price': sku_obj.price,
                    'img': sku_obj.default_image_url,
                    'goods_num': v.decode()
                })
            return Response({'msg': 'OK', 'code': 200, 'data': cart_list})
        else:
            return Response({'msg': '请登录', 'code': 400})

    def delete(self, request):
        """
        {'token': 'xxxxxxxxxxxxxx', 'goods_id': ['1]}
        """
        token = request.data.get('token')
        goods_id = request.data.get('goods_id')
        # 解析用户
        user_info = check_token(token)
        if user_info:
            user_id = user_info.get('user_id')
            redis_cart.hdel(user_id, goods_id)
            return Response({'msg': '删除成功', 'code': 200})
        else:
            return Response({'msg': '请重新登录', 'code': 400})


"""
数量在redis中，点击前端的购物车加减数量按钮，需要修改redis当中的数量，以便结算是获取
    
"""


class AddCartNumView(APIView):
    """
    购物车增加数量
    """
    def post(self, request):
        """
        {'token': 'xxxxxxxxxxxx', 'goods_id': ['1']}
        """
        token = request.data.get('token')
        goods_id = request.data.get('goods_id')
        # 解析用户信息
        user_info = check_token(token)
        if user_info:
            user_id = user_info.get('user_id')
            redis_cart.hincrby(user_id, goods_id, 1)
            return Response({'msg': 'OK', 'code': 200})
        else:
            return Response({'msg': '请登录', 'code': 400})


class MinusCartNumView(APIView):
    """
    购物车增加数量
    """
    def post(self, request):
        """
        {'token': 'xxxxxxxxxxxx', 'goods_id': ['1']}
        """
        token = request.data.get('token')
        goods_id = request.data.get('goods_id')
        # 解析用户信息
        user_info = check_token(token)
        if user_info:
            user_id = user_info.get('user_id')
            # 减数量，需要判断redis中数量不小于1
            goods_num = redis_cart.hget(user_id, goods_id).decode()
            if int(goods_num) > 1:
                # 商品数量增量 减1
                redis_cart.hincrby(user_id, goods_id, -1)
                return Response({'msg': 'OK', 'code': 200})
            else:
                return Response({'msg': '点不动了', 'code': 400})
        else:
            return Response({'msg': '请登录', 'code': 400})








